home *** CD-ROM | disk | FTP | other *** search
/ Ham Radio 2000 #2 / Ham Radio 2000 - Volume 2.iso / HAMV2 / TCP_IP / TNOS230S / CRONTAB.C < prev    next >
Encoding:
C/C++ Source or Header  |  1997-08-18  |  7.6 KB  |  391 lines

  1. #include "global.h"
  2. #include "ctype.h"
  3. #include "commands.h"
  4. #include "mbuf.h"
  5. #include "netuser.h"
  6. #ifndef MSDOS
  7. #include "tcp.h"
  8. #include "usock.h"
  9. #endif
  10. #include "files.h"
  11.  
  12. #if !defined(_lint)
  13. static char rcsid[] OPTIONAL = "$Id: crontab.c,v 1.18 1997/08/19 01:19:22 root Exp root $";
  14. #endif
  15.  
  16. #ifdef CRONTAB
  17.  
  18. struct crontab {
  19.     char minute[60];
  20.     char hour[24];
  21.     char day[31];
  22.     char dayofweek[7];
  23.     char month[12];
  24.     char *cmd;
  25.     struct crontab *next;
  26. };
  27. #define NULLCRONTAB ((struct crontab *)0)
  28.  
  29. static struct crontab *CRON;
  30. static int CRONactive = -1;
  31.  
  32. extern struct cmds Cmds[];
  33. extern const char *Days[7], *Months[12];    /*lint !e15 */
  34. #ifdef LOCK
  35. extern int Kblocked;
  36. #endif
  37.  
  38.  
  39. static void processcrontab (void);
  40. static void listsegment (char *field, int size, int offset);
  41. static void parsesegment (char *field, int size, char *val, int offset, char **tbl);
  42. static void addline (int argc, char *argv[]);
  43. static int docronload (int argc,char *argv[],void *p);
  44. static int docronlist (int argc,char *argv[],void *p);
  45. static int docronadd (int argc,char *argv[],void *p);
  46. static int docronclear (int argc,char *argv[],void *p);
  47. static int docrondel (int argc,char *argv[],void *p);
  48.  
  49.  
  50. /* crontab subcommand table */
  51. static struct cmds CRONtab[] = {
  52.     { "add",        docronadd,        0, 7, "cron add min hour day month dayofweek \"cmd\"" },
  53.     { "clear",        docronclear,        0, 0, NULLCHAR },
  54.     { "delete",        docrondel,        0, 2, "cron delete entry#" },
  55.     { "list",        docronlist,        0, 0, NULLCHAR },
  56.     { "load",        docronload,        0, 0, NULLCHAR },
  57.     { NULLCHAR,        NULL,            0, 0, NULLCHAR }
  58. };
  59.  
  60.  
  61. int
  62. docrontab (argc, argv, p)
  63. int argc;
  64. char *argv[];
  65. void *p;
  66. {
  67.     return subcmd (CRONtab, argc, argv, p);
  68. }
  69.  
  70.  
  71. static int
  72. docronadd (argc, argv, p)
  73. int argc;
  74. char *argv[];
  75. void *p OPTIONAL;
  76. {
  77.     if (argc >= 7)
  78.         addline (--argc, ++argv);        /*lint !e608 */
  79.     return 0;
  80. }
  81.  
  82.  
  83. static int
  84. docrondel (argc, argv, p)
  85. int argc OPTIONAL;
  86. char *argv[];
  87. void *p OPTIONAL;
  88. {
  89. struct crontab *cr, *tmp = NULLCRONTAB;
  90. int i;
  91.     i = (atoi (argv[1]) - 1);
  92.     if (!i)    {
  93.         cr = CRON;
  94.         CRON = cr->next;
  95.         free (cr->cmd);
  96.         free (cr);
  97.     } else    {
  98.         for (cr = CRON; cr; cr = tmp,i--)    {
  99.             if (i == 1)    {
  100.                 tmp = cr->next;
  101.                 cr->next = tmp->next;
  102.                 free (tmp->cmd);
  103.                 free (tmp);
  104.                 break;
  105.             }
  106.         }
  107.     }
  108.     return 0;
  109. }
  110.  
  111.  
  112. static int
  113. docronclear (argc, argv, p)
  114. int argc OPTIONAL;
  115. char *argv[];
  116. void *p OPTIONAL;
  117. {
  118. struct crontab *cr, *tmp;
  119.  
  120.     for (cr = CRON; cr; cr = tmp)    {
  121.         tmp = cr->next;
  122.         free (cr->cmd);
  123.         free (cr);
  124.     }
  125.     CRON = NULLCRONTAB;
  126.     if (argv)
  127.         tprintf ("Crontab cleared!\n");
  128.     return 0;
  129. }
  130.  
  131.  
  132. static int
  133. docronload (argc, argv, p)
  134. int argc;
  135. char *argv[];
  136. void *p OPTIONAL;
  137. {
  138. FILE *fp;
  139. char const *filename = CRONTABFile;
  140. char buffer[1024 + 9], *cp;
  141.  
  142.     if (argc > 1)    {
  143.         filename = argv[1];
  144.     } else {
  145.         (void) docronclear (1, (char **)0, (void *)0);
  146.     }
  147.     if ((fp = fopen (filename, READ_TEXT)) != NULLFILE)    {
  148.         while (!feof(fp))    {
  149.             strcpy (buffer, "cron add ");
  150.             if (fgets (&buffer[9], 1024, fp))    {
  151.                 cp = skipwhite (&buffer[9]);
  152.                 if (*cp && *cp != '#')
  153.                     (void) cmdparse (Cmds, buffer, NULL);
  154.             }
  155.         }
  156.         (void) fclose (fp);
  157.     }
  158.     if (argv)
  159.         tprintf ("Crontab loaded!\n");
  160.         return 0;
  161. }
  162.  
  163.  
  164. static int
  165. docronlist (argc, argv, p)
  166. int argc OPTIONAL;
  167. char *argv[] OPTIONAL;
  168. void *p OPTIONAL;
  169. {
  170. struct crontab *c;
  171. int i = 1;
  172.  
  173.     for (c = CRON; c; c = c->next)    {
  174.         tprintf ("%3d:  ", i++);
  175.         listsegment (c->minute, 60, 0);
  176.         listsegment (c->hour, 24, 0);
  177.         listsegment (c->day, 31, 1);
  178.         listsegment (c->month, 12, 1);
  179.         listsegment (c->dayofweek, 7, 0);
  180.         tprintf ("\"%s\"\n", c->cmd);
  181.     }
  182.     return 0;
  183. }
  184.  
  185.  
  186. /* Start up cron server */
  187. int
  188. cron1 (argc, argv, p)
  189. int argc OPTIONAL;
  190. char *argv[] OPTIONAL;
  191. void *p OPTIONAL;
  192. {
  193.     if (CRONactive != -1)
  194.         return 0;
  195.  
  196.     (void) ksignal (Curproc, 0);   /* Don't keep the parser waiting */
  197.     chname (Curproc, "Cron server");
  198.     CRONactive = Curproc->output;
  199.     (void) docronload (1, (char **)0, (void *)0);
  200.  
  201.     server_disconnect_io ();
  202.     while (CRONactive != -1)    {
  203.         (void) kpause (60000);
  204.         processcrontab ();
  205.     }
  206.     return 0;
  207. }
  208.  
  209.  
  210.  
  211. /* Shut down cron server */
  212. int
  213. cron0 (argc, argv, p)
  214. int argc OPTIONAL;
  215. char *argv[] OPTIONAL;
  216. void *p OPTIONAL;
  217. {
  218.     return (deleteserver (&CRONactive));
  219. }
  220.  
  221.  
  222. static void
  223. listsegment (field, size, offset)
  224. char *field;
  225. int size, offset;
  226. {
  227. int i, k, usecomma = 0;
  228.  
  229.     /* special case check for '*' */
  230.     for (i = 0; i < size; i++)    {
  231.         if (!field[i])
  232.             break;
  233.     }
  234.     if (i == size)
  235.         tputc ('*');
  236.     else    {    /* otherwise, one or more (but not ALL) values */
  237.         for (i = 0; i < size; i++)    {
  238.             /* Skip if this index is clear */
  239.             if (!field[i])
  240.                 continue;
  241.  
  242.             /* We have at least ONE value here, so place a comma, if needed */
  243.             if (usecomma)
  244.                 tputc (',');
  245.             else
  246.                 usecomma = 1;
  247.             
  248.             if ((i + 1) == size || !field[i + 1])
  249.                 tprintf ("%-d", i + offset);
  250.             else    {
  251.                 for (k = i + 1; k < size; k++)    {
  252.                     if (!field[k])
  253.                         break;
  254.                 }
  255.                 k--;
  256.                 tprintf ("%-d-%-d", i + offset, k + offset);
  257.                 i = k;
  258.             }
  259.         }
  260.     }
  261.     tputc (' ');
  262. }
  263.  
  264.  
  265. static void
  266. parsesegment (field, size, val, offset, tbl)
  267. char *field;
  268. int size;
  269. char *val;
  270. int offset;
  271. char **tbl;
  272. {
  273. char *cp = val, *temp, itwas;
  274. int val1, val2, i, stepval;
  275.  
  276.     while (cp && *cp)    {
  277.         itwas = 0;
  278.         if ((temp = strpbrk (cp, "-,")) != NULLCHAR)    {
  279.             itwas = *temp;
  280.             *temp++ = 0;
  281.         }
  282.         if (*cp == '*')    {
  283.             for (i = 0; i < size; i++)
  284.                 field[i] = 1;
  285.         } else if (!isdigit (*cp)){
  286.             for (i = 0; i < size; i++)    {
  287.                 if (!stricmp (tbl[i], cp))    {
  288.                     field[i] = 1;
  289.                     break;
  290.                 }
  291.             }
  292.         } else {
  293.             val1 = atoi (cp);
  294.             if (offset)
  295.                 val1 -= offset;
  296.             if (itwas == '-' && temp)    {
  297.                 cp = temp;
  298.                 if ((temp = strpbrk (cp, ",/")) != NULLCHAR)    {
  299.                     itwas = *temp;
  300.                     *temp++ = 0;
  301.                 }
  302.                 val2 = atoi (cp);
  303.                 if (!offset)
  304.                     val2++;
  305.                 if (itwas == '/' && temp)    {
  306.                     cp = temp;
  307.                     if ((temp = strpbrk (cp, "-,")) != NULLCHAR)
  308.                         *temp++ = 0;
  309.                     stepval = atoi (cp);
  310.                 } else
  311.                     stepval = 1;
  312.                 for (i = val1; i < val2 && i < size; i += stepval)
  313.                     field[i] = 1;
  314.             } else    {
  315.                 field[val1] = 1;
  316.             }
  317.         }
  318.         cp = temp;
  319.     }
  320. }
  321.  
  322.  
  323. static void
  324. addline (argc, argv)
  325. int argc;
  326. char *argv[];
  327. {
  328. struct crontab *c;
  329. int i;
  330.  
  331.     c = (struct crontab *) callocw (1, sizeof (struct crontab));
  332.     if (c != NULLCRONTAB)    {
  333.         parsesegment (c->minute, 60, argv[0], 0, (char **)0);
  334.         parsesegment (c->hour, 24, argv[1], 0, (char **)0);
  335.         parsesegment (c->day, 31, argv[2], 1, (char **)0);
  336.         parsesegment (c->month, 12, argv[3], 1, (char **)Months);
  337.         parsesegment (c->dayofweek, 7, argv[4], 0, (char **)Days);
  338.         argc--;
  339.         for (i = 5; i < argc; i++)    {
  340.             argv[i][strlen(argv[i])] = ' ';
  341.         }
  342.         c->cmd = strdup (argv[5]);
  343.         c->next = CRON;
  344.         CRON = c;
  345.     }
  346. }
  347.  
  348.  
  349. static void
  350. processcrontab ()
  351. {
  352. struct crontab *c;
  353. time_t now;
  354. struct tm *tmp, t;
  355. char *cmd;
  356. #ifdef LOCK
  357. int lockedstate;
  358. #endif
  359.  
  360.     now = time ((time_t *)0);
  361.     tmp = localtime (&now);
  362.     /* Since calls from cmdparse CAN overwrite this temp
  363.        buffer, we copy the time buffer locally */
  364.     memcpy (&t, tmp, sizeof (struct tm));
  365.     for (c = CRON; c; c = c->next)    {
  366.         if (!c->minute[t.tm_min])
  367.             continue;
  368.         if (!c->hour[t.tm_hour])
  369.             continue;
  370.         if (!c->day[t.tm_mday - 1])
  371.             continue;
  372.         if (!c->dayofweek[t.tm_wday])
  373.             continue;
  374.         if (!c->month[t.tm_mon])
  375.             continue;
  376.         cmd = _variable_expansion (strdup (c->cmd));
  377. #ifdef LOCK
  378.         lockedstate = Kblocked;
  379.         Kblocked = 0;
  380. #endif
  381.         (void) cmdparse (Cmds, cmd, NULL);
  382. #ifdef LOCK
  383.         Kblocked = lockedstate;
  384. #endif
  385.         free (cmd);
  386.     }
  387. }
  388.  
  389.  
  390. #endif /* CRONTAB */
  391.